#include "Date.h"
#include <iostream>
using namespace std;

Date::Date(int year, int month, int day)
	:year(year),
	month(month),
	day(day)
{

}
Date::Date()
	:year(2010),
	month(6),
	day(17)
{

}

void Date::display() const
{
	cout << this->year << "/" << this->month << "/" << this->day << endl;
}

bool Date::isLeap(int year) const
{
	if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
		return true;
	}
	return false;
}

int Date::getMonthDay(int year, int month) const
{
	switch(month){
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			return 31;
		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
		case 2:
			if(this->isLeap(year))
				return 29;
			else
				return 28;
	}
}

int Date::getYearDay(int year) const
{
	int days = 0;
	for(int i = 1; i <= 12; i++){
		days += this->getMonthDay(year, i);
	}
	return days;
}

/*
	d: 2010 6 17
	d1: 2019 5 24

	计算2010年剩余天数 + (2011 ~ 2018)整年天数 + 2019年过去的天数 
*/

int Date::operator - (const Date& rhs) const
{
	//先计算rhs对象当前剩余天数
	int old = 0;
	for(int i = rhs.getMonth(); i <= 12; i++){
		old += getMonthDay(rhs.getYear(), i);
	} 

	old -= rhs.getDay();

	//中间整年的天数
	int mid = 0;
	for(int i = rhs.getYear() + 1; i < this->year; i++){
		mid += getYearDay(i);
	}

	int cur = 0;
	//当前年过去的天数
	for(int i = 1; i < this->month; i++){
		cur += getMonthDay(this->year, i);
	}	
	cur += this->day;
	if(this->year == rhs.getYear()){
		return old + mid + cur - getYearDay(year);
	}
	return old + mid + cur;
}

const Date& Date::operator ++ ()
{
	int day = getMonthDay(this->year, this->month);	
	this->day++;
	if(this->day > day){
		this->day = 1;
		this->month++;
	}

	if(this->month > 12){
		this->year++;
		this->month = 1;
	}
	return *this;
}

const Date Date::operator++(int)
{
	Date tmp = *this;
	++(*this);
	return tmp;
}

const Date& Date::operator -- ()
{
	this->day--;
	if(day < 1){
		this->day = getMonthDay(this->year, (this->month - 1 < 1) ? 12 : this->month -1);
		this->month--;
	}

	if(this->month < 1){
		this->month = 12;
		this->year--;
	}
	return *this;
}

const Date Date::operator--(int)
{
	Date tmp = *this;
	--(*this);
	return tmp;
}


ostream& operator << (ostream& out, const Date& d)
{
	out << d.getYear() << "/" << d.getMonth() << "/" << d.getDay();
	return out;
}

